import os
from src.core import log
from src.db import dbm, dbs
from src.mod import safe_remove
from src.core.variables.function import *
from src.core.variables.constant import *
from src.core.variables.exception import *
from src.core.variables.temp import MIDDLEWARE
from src.apps.hosting.stater.controller import Jar_manager, Static_manager
from src.mod.file_exchanger.distribute import Distribute, Distribution_failed
from src.core.variables.status import (
    ERROR_CODE,
    ERROR_CODE_CUSTOMIZE,
    SUCCESS_CODE,
    SUCCESS_CODE_CUSTOMIZE,
)
from src.db.library.sys_default import User
from src.schema.hosting import register_static_schema, register_java_schema
from src.core.variables.cls import HOSTING_JAVA_RUNNER_DICT, HOSTING_STATIC_RUNNER_DICT


def java(schema: register_java_schema, user: User):
    """app_java注册"""
    try:
        # 分发文件
        # 投入仓库
        save_repo_path = Distribute.temp_to_repo(
            schema.save_path, schema.node, schema.time_dir, schema.alias
        )
        log.DEBUG(f"文件 {schema.save_path} 已分发到仓库: {save_repo_path}")
        log.INFO(f"文件 {schema.save_path} 已分发到仓库")
        # 写入数据库
        with dbm.get("hosting_Java") as db_session:
            from sqlalchemy.orm import scoped_session
            db_session: scoped_session
            app_id = CREATE_ID()
            data = {
                "app_id": app_id,
                "alias": schema.alias,
                "file_name": os.path.basename(schema.save_path),
                "node": schema.node,
                "status": "dead",
                "create_time": schema.time_dir,
                "deploy_time": schema.time_dir,
                "log_path": "",
                "keepalive": schema.keepalive,
                "notes": schema.notes,
                "version": schema.version,
                "inpara": schema.inpara,
                "run_path": "",
                "pid": "",
                "port": schema.port,
                "project": "",
                "team": "",
                "modules": "",
                "runner": "Java",
                "runner_version": "",
                "create_user": user.uid,
                "source": "register",
                "time_dir": schema.time_dir,
                "before_id": "0",
            }
            db_session.add(dbs.hosting_Java.App(**data))
            if dbm.commit(db_session):
                HOSTING_JAVA_RUNNER_DICT[app_id] = Jar_manager(app_id)
                return SUCCESS_CODE_CUSTOMIZE({"app_id": app_id}, 200)
            else:
                raise MAIN_EXCEPTION(f"提交数据库更改失败！")
    except Distribution_failed as e:
        return ERROR_CODE_CUSTOMIZE(f"分发失败: {e}", 500)
    except Exception as e:
        log.ERROR(f"注册失败: {e}")
        return ERROR_CODE_CUSTOMIZE(f"注册失败: {e.__class__}", 500)


def static(schema: register_static_schema, user: User):
    """app_web注册"""
    try:
        # 将nginx_conf添加到nginx.conf中进行语法校验
        app_id = CREATE_ID()
        try:
            conf_file_path = f"{MIDDLEWARE.NGINX.conf_d_dir}/{app_id}_check.conf"
            if not os.path.exists(os.path.dirname(conf_file_path)):
                os.makedirs(os.path.dirname(conf_file_path))
            with open(conf_file_path, "w", encoding="utf-8") as f:
                run_path = f'{CONF.PATH.RUN_STATIC}/{schema.alias}'
                nginx_conf = schema.nginx_conf.replace('@运行池', run_path)
                f.write(nginx_conf)
            MIDDLEWARE.NGINX.change_include(conf_file_path, 'add')
            check_result = MIDDLEWARE.NGINX.check()
            if check_result:
                if conf_file_path in check_result:
                    check_result = check_result.replace(conf_file_path, "当前配置")
                if MIDDLEWARE.NGINX.conf_path in check_result:
                    check_result = check_result.replace(MIDDLEWARE.NGINX.conf_path, "nginx.conf")
                if not 'test is successful' in check_result:
                    return ERROR_CODE_CUSTOMIZE(check_result, 400)
        finally:
            MIDDLEWARE.NGINX.change_include(conf_file_path, 'remove')
            safe_remove(conf_file_path)
        # 将应用程序投入仓库
        save_repo_path = Distribute.temp_to_repo(
            schema.save_path, schema.node, schema.time_dir, schema.alias
        )
        log.DEBUG(f"文件 {schema.save_path} 已分发到仓库: {save_repo_path}")
        log.INFO(f"文件 {schema.save_path} 已分发到仓库")
        # 写入数据库
        with dbm.get("hosting_Static") as db_session:
            data = {
                "app_id": app_id,
                "before_id": "0",
                "alias": schema.alias,
                "file_name": os.path.basename(schema.save_path),
                "node": schema.node,
                "status": "unmapped",
                "create_time": schema.time_dir,
                "deploy_time": schema.time_dir,
                "notes": schema.notes,
                "version": schema.version,
                "run_path": "",
                "project": "",
                "team": "",
                "modules": "",
                "runner": "nginx",
                "runner_version": "",
                "create_user": user.uid,
                "source": "register",
                "time_dir": schema.time_dir,
                "nginx_conf": schema.nginx_conf,
            }
            db_session.add(dbs.hosting_Static.App(**data))
            if dbm.commit(db_session):
                HOSTING_STATIC_RUNNER_DICT[app_id] = Static_manager(app_id)
                return SUCCESS_CODE_CUSTOMIZE({"app_id": app_id}, 200)
            else:
                raise MAIN_EXCEPTION(f"提交数据库更改失败！")
    except Distribution_failed as e:
        return ERROR_CODE_CUSTOMIZE(f"分发失败: {e}", 500)
    except Exception as e:
        log.ERROR(f"注册失败: {e}")
        return ERROR_CODE_CUSTOMIZE(f"注册失败: {e.__class__}", 500)